// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Styling/CoreStyle.h"
#include "Widgets/Accessibility/SlateWidgetAccessibleTypes.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Widgets/SLeafWidget.h"

#include "SCircumferenceMarkerWidget.generated.h"

class FPaintArgs;
class FSlateRect;
class FSlateWindowElementList;
class FWidgetStyle;
struct FGeometry;
struct FSlateBrush;

USTRUCT(BlueprintType)
struct FCircumferenceMarkerEntry
{
	GENERATED_BODY()

	// 将标记放置在圆周围的角度（度）
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ForceUnits=deg))
	float PositionAngle = 0.0f; //位置角度

	// 旋转标记图像的角度（度）
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ForceUnits=deg))
	float ImageRotationAngle = 0.0f; //图像旋转角度
};

class SCircumferenceMarkerWidget : public SLeafWidget
{
	SLATE_BEGIN_ARGS(SCircumferenceMarkerWidget)
		: _MarkerBrush(FCoreStyle::Get().GetBrush("Throbber.CircleChunk"))
		, _Radius(48.0f)
	{
	}
		/** 圆周上每个标记的外观 */
		SLATE_ARGUMENT(const FSlateBrush*, MarkerBrush)
		/** 应在哪些角度绘制标记 */
		SLATE_ARGUMENT(TArray<FCircumferenceMarkerEntry>, MarkerList)
		/** 圆的半径 */
		SLATE_ATTRIBUTE(float, Radius)
		/** 标记的颜色和不透明度 */
		SLATE_ATTRIBUTE(FSlateColor, ColorAndOpacity)
	SLATE_END_ARGS()

public:
	/**
	 * 构建控件
	 * @param InArgs Slate参数
	 */
	void Construct(const FArguments& InArgs);

	SCircumferenceMarkerWidget();

	//~SWidget 接口
	/**
	 * 绘制控件
	 * @param Args 绘制参数
	 * @param AllottedGeometry 分配的几何信息
	 * @param MyCullingRect 剔除矩形
	 * @param OutDrawElements 绘制元素列表
	 * @param LayerId 图层ID
	 * @param InWidgetStyle 控件样式
	 * @param bParentEnabled 父控件是否启用
	 * @return 图层ID
	 */
	virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
	/**
	 * 计算期望大小
	 * @param LayoutScaleMultiplier 布局缩放乘数
	 * @return 期望大小
	 */
	virtual FVector2D ComputeDesiredSize(float) const override;
	/**
	 * 计算易变性
	 * @return 总是返回true
	 */
	virtual bool ComputeVolatility() const override { return true; }
	//~SWidget 接口结束

	/**
	 * 设置半径
	 * @param NewRadius 新的半径值
	 */
	void SetRadius(float NewRadius);
	/**
	 * 设置标记列表
	 * @param NewMarkerList 新的标记列表
	 */
	void SetMarkerList(TArray<FCircumferenceMarkerEntry>& NewMarkerList);

private:
	/**
	 * 获取标记的渲染变换
	 * @param Marker 标记条目
	 * @param BaseRadius 基础半径
	 * @param HUDScale HUD缩放
	 * @return 渲染变换
	 */
	FSlateRenderTransform GetMarkerRenderTransform(const FCircumferenceMarkerEntry& Marker, const float BaseRadius, const float HUDScale) const;

private:
	/** 圆周上每个标记的外观 */
	const FSlateBrush* MarkerBrush; //标记画刷

	/** 在十字准星中心周围放置ReticleCornerImage图标的角度 */
	TArray<FCircumferenceMarkerEntry> MarkerList; //标记列表

	/** 圆的半径 */
	TAttribute<float> Radius; //半径

	/** 标记的颜色和不透明度 */
	TAttribute<FSlateColor> ColorAndOpacity; //颜色和不透明度
	bool bColorAndOpacitySet; //颜色和不透明度是否设置

	/** 十字准星角图像是否放置在扩散半径之外 */
	//@TODO: 将其改为0-1浮点数对齐方式（例如，在半径内部/之上/外部）？
	uint8 bReticleCornerOutsideSpreadRadius : 1; //十字准星角是否在扩散半径外
};